package dxn.nl.export.deal.export;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterBuilder;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import dxn.nl.export.deal.convert.EasyExcelLocalDateConverter;
import dxn.nl.export.deal.convert.EasyExcelLocalDateTimeConverter;
import dxn.nl.file.client.model.dto.CsExportExcelHeadDto;
import dxn.nl.file.client.model.dto.CsExportExcelSheetHeadDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.util.CollectionUtils;

import java.util.*;

@Slf4j
public class ExportExcelWriterBiz implements DisposableBean
{
    private String filePath;
    private ExcelWriter excelWriter;
    private HashMap<String,WriteSheet> sheetMap = new HashMap<>();
    private HashMap<String,Integer> sheetCountMap = new HashMap<>();
    private final HashMap<String,List<List<String>>> sheetHeadStrMap = new HashMap<>();
    private final HashMap<String,CsExportExcelSheetHeadDto> sheetHeadMap;
    private final String defaultSheetName;
    private final int sheetMaxCount = 150000;

    public ExportExcelWriterBiz(HashMap<String,CsExportExcelSheetHeadDto> sheetHeadMap, String filePath)
    {
        for(Map.Entry<String,CsExportExcelSheetHeadDto> entry:sheetHeadMap.entrySet())
        {
            List<CsExportExcelHeadDto> headDtos =entry.getValue().getHeadDtoList();
            List<List<String>> excelHeads = new ArrayList<>();
            for (CsExportExcelHeadDto head : headDtos) {
                List<String> titles = head.getTitle();
                if (titles == null) {
                    titles = List.of("");
                }
                excelHeads.add(titles);
            }
            sheetHeadStrMap.put(entry.getKey(),excelHeads);
        }

        this.sheetHeadMap = sheetHeadMap;
        if(!CollectionUtils.isEmpty(sheetHeadMap))
        {
            this.defaultSheetName = sheetHeadMap.keySet().stream().findFirst().get();
        }
        else
        {
            this.defaultSheetName = "default";
        }
        this.filePath = filePath;
    }

    public boolean hasMaxCount(String sheetName)
    {
        Integer count = sheetCountMap.get(sheetName);
        if(count == null)
        {
            return false;
        }
        if(count>=sheetMaxCount)
        {
            return true;
        }
        return false;
    }

    public int getSheetCount()
    {
        return sheetHeadMap.size();
    }

    public Set<String> getAllSheetName()
    {
        return sheetHeadMap.keySet();
    }

    public int writerData(String sheetName,byte[] data)
    {
        if(StringUtils.isBlank(sheetName))
        {
            sheetName = defaultSheetName;
        }
        ExcelWriter excelWriterTemp = getExcelWriter();

        WriteSheet writeSheet = sheetMap.get(sheetName);
        if(writeSheet == null)
        {
            ExcelWriterSheetBuilder sheetBuilder = EasyExcel.writerSheet(sheetName);
            HorizontalCellStyleStrategy horizontalCellStyleStrategy = new HorizontalCellStyleStrategy(StyleUtils.getHeadStyle(), StyleUtils.getContentStyle());
            sheetBuilder.registerWriteHandler(horizontalCellStyleStrategy);
            CsExportExcelSheetHeadDto sheetHeadDto = sheetHeadMap.get(sheetName);
            if(sheetHeadDto != null && !CollectionUtils.isEmpty(sheetHeadDto.getHeadDtoList()))
            {
                sheetBuilder.head(sheetHeadStrMap.get(sheetName));
                sheetBuilder.registerWriteHandler(new CusColumnWidthStyleStrategy(sheetHeadDto.getHeadDtoList()));
            }

            writeSheet = sheetBuilder.build();
            sheetMap.put(sheetName,writeSheet);
        }

        List<List<Object>> writerList = new ArrayList<>();

        CsExportExcelSheetHeadDto sheetHeadDto = sheetHeadMap.get(sheetName);
        if(sheetHeadDto.isHasTitle())
        {
            List<JSONObject> jsonObjectList = JSON.parseArray(data, JSONObject.class);
            if (!CollectionUtils.isEmpty(jsonObjectList)) {
                for (JSONObject jobj : jsonObjectList) {
                    List<Object> row = new ArrayList<>();
                    for (CsExportExcelHeadDto head : sheetHeadDto.getHeadDtoList()) {
                        Object o = jobj.get(head.getKey());
                        row.add(o);
                    }
                    writerList.add(row);
                }
            }
        }
        else {
            writerList = JSON.parseObject(data, (new TypeReference<List<Object>>(){}).getType());
        }

        if(!CollectionUtils.isEmpty(writerList))
        {
            excelWriterTemp.write(writerList,writeSheet);
            return writerList.size();
        }
        return 0;
    }

    private ExcelWriter getExcelWriter() {
        if (excelWriter == null) {
            ExcelWriterBuilder builder = EasyExcel.write(filePath);
            builder.registerConverter(new EasyExcelLocalDateTimeConverter());
            builder.registerConverter(new EasyExcelLocalDateConverter());
            excelWriter = builder.build();
        }
        return excelWriter;
    }

    public void newExcelWriter(String filePath)
    {
        this.filePath = filePath;
        excelWriter.close();
        sheetMap.clear();
        sheetCountMap.clear();
    }

    @Override
    public void destroy() {
        try{
            if(excelWriter != null)
            {
                excelWriter.finish();
            }
        }
        catch (Exception ex)
        {

        }
    }
}
